﻿using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows;
using System.Diagnostics.Eventing.Reader;

namespace Main.Controls
{
    public class AutoTextBlock : Control
    {
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
            "Text", typeof(string), typeof(AutoTextBlock), new PropertyMetadata(default(string), OnTextChanged));

        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }

        private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            AutoTextBlock autoTextBlock = d as AutoTextBlock;
            if (autoTextBlock != null)
            {
                autoTextBlock.InvalidateVisual();
            }
        }

        protected override void OnRender(DrawingContext drawingContext)
        {            
            base.OnRender(drawingContext);
            
            if (!string.IsNullOrEmpty(Text))
            {

                string originText = Text;
                string currentText= Text;
                int wrappedCount = 0;
                double maxWidth = ActualWidth;
                double maxHeight = ActualHeight;

                var formattedText = new FormattedText(
                    currentText,
                    System.Globalization.CultureInfo.CurrentCulture,
                    FlowDirection.LeftToRight,
                    new Typeface(FontFamily, FontStyle, FontWeight, FontStretch),
                    FontSize,
                    Foreground
                );
                while (true)
                {


                    double currentWidth = formattedText.Width;
                    double currentHeight = formattedText.Height;

                    if(currentWidth<=maxWidth&&currentHeight<=maxHeight || FontSize<=1)
                    {
                        break;
                    }

                    double fontSize = FontSize;
                    //计算是否还可以折行
                    _GetWrappedText(originText, ref currentText, ref wrappedCount,ref fontSize , currentWidth, currentHeight,maxWidth, maxHeight);
                    FontSize= fontSize;       
                    formattedText = new FormattedText(
                        currentText,
                        System.Globalization.CultureInfo.CurrentCulture,
                        FlowDirection.LeftToRight,
                        new Typeface(FontFamily, FontStyle, FontWeight, FontStretch),
                        FontSize,
                        Foreground
                    );
                }
                

                          

                
                drawingContext.DrawText(formattedText, new Point(0, 0));
                //drawingContext.Pop();
            }
        }


        void _GetWrappedText(string originText, ref string currentText,ref int wrappedCount,ref double fontSize,double currentWidth, double currentHeight,double maxWidth,double maxHeight)
        {
            int maxWrappedCount = 2;
            //已经折行或高度已经超了
            if (currentHeight > maxHeight || wrappedCount >= maxWrappedCount)
            {
                currentText = originText;
                fontSize -= 1;
                wrappedCount = 0;
                return;
            }

            //已经折行，但是未尝试降低字号
            if (wrappedCount < maxWrappedCount && wrappedCount > 0)
            {
                wrappedCount++;
                fontSize -= 1;
                return;
            }
            

            //maxWidth = maxWidth * 0.9;

            //需要多少行
            var row_needed=Math.Ceiling(currentWidth / maxWidth);
            //是否可以折行
            if (row_needed * currentHeight <= maxHeight)//可以折行
            {
                //多少文字一行
                var char_per_row=(int)Math.Floor(originText.Length*maxWidth/ currentWidth);
                if(char_per_row <= 0)
                {
                    char_per_row = 1;
                }

                int pos = 0;
                StringBuilder sb = new StringBuilder();
                while (true)
                {
                    if (pos >= originText.Length)
                    {
                        break;
                    }

                    int sub_len = Math.Min(char_per_row, originText.Length - pos);
                    sub_len=_GetSubstringLenNotInEnglishWord(pos, sub_len,originText);                                     

                    if (pos+ sub_len >= originText.Length)
                    {
                        sb.Append($"{originText.Substring(pos, sub_len)}");
                    }
                    else
                    {
                        sb.Append($"{originText.Substring(pos, sub_len)}\r\n");
                    }

                    pos += sub_len;
                }
                currentText= sb.ToString();

                wrappedCount = 1;

                return;
            }
            else//不能折行
            {
                currentText = originText;
                fontSize -= 1;
                return;
            }
        }

        int _GetSubstringLenNotInEnglishWord(int pos,int originLen,string text)
        {
            int pos2 = pos + originLen;
            if (pos2 - 1 < 0)
            {
                return originLen;
            }

            if (pos2 >= text.Length)
            {
                return pos2 - pos;
            }

            char ch1 = text[pos2 - 1];
            char ch2 = text[pos2];
            if ((ch1 >= '0' && ch1 <= '9') || ch1 == '.')
            {
                while (ch2 >= '0' && ch2 <= '9')
                {
                    pos2++;
                    if (pos2 >= text.Length)
                    {
                        return pos2 - pos;
                    }
                }
                return pos2 - pos;
            }
            else if ((ch1 >= 'A' && ch1 <= 'Z') || (ch1 >= 'a' && ch1 <= 'z'))
            {
                while ((ch2 >= 'A' && ch2 <= 'Z') || (ch2 >= 'a' && ch2 <= 'z'))
                {
                    pos2++;
                    if (pos2 >= text.Length)
                    {
                        return pos2 - pos;
                    }
                }
                return pos2 - pos;
            }
            else
            {
                return originLen;
            }
        }


        //protected override void OnRender(DrawingContext drawingContext)
        //{
        //    base.OnRender(drawingContext);
        //    if (!string.IsNullOrEmpty(Text))
        //    {
        //        Size maxSize = new Size(ActualWidth, ActualHeight);
        //        var formattedText = new FormattedText(
        //            Text,
        //            System.Globalization.CultureInfo.CurrentCulture,
        //            FlowDirection.LeftToRight,
        //            new Typeface(FontFamily, FontStyle, FontWeight, FontStretch),
        //            FontSize,
        //            Foreground
        //        );

        //        double width = formattedText.Width;
        //        double height = formattedText.Height;
        //        double scale = Math.Min(maxSize.Width / width, maxSize.Height / height);

        //        drawingContext.PushTransform(new ScaleTransform(scale, scale));
        //        drawingContext.DrawText(formattedText, new Point(0, 0));
        //        drawingContext.Pop();
        //    }
        //}
    }
}
